package cn.cdeden.knowledge.controller.calendar;


import cn.cdeden.common.core.domain.R;
import cn.cdeden.common.core.utils.MapstructUtils;
import cn.cdeden.common.core.utils.page.TableDataInfo;
import cn.cdeden.common.satoken.utils.LoginHelper;
import cn.cdeden.knowledge.domain.*;
import cn.cdeden.knowledge.domain.dto.*;
import cn.cdeden.knowledge.domain.vo.CalendarVO;
import cn.cdeden.knowledge.domain.vo.SysCalendarVO;
import cn.cdeden.knowledge.domain.vo.UserVO;
import cn.cdeden.knowledge.service.*;
import cn.cdeden.knowledge.utils.BeanCopyUtil;
import cn.cdeden.knowledge.utils.DateUtil;
import cn.cdeden.system.api.RemoteDeptService;
import cn.cdeden.system.api.RemoteUserService;
import cn.cdeden.system.api.domain.vo.RemoteUserVo;
import cn.cdeden.system.api.model.LoginUser;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
* @author Yu.
* @date 2023-02-02
**/
@RestController
@RequiredArgsConstructor
//@Api(tags = "用户日程信息管理")
@Slf4j
@RequestMapping("/api/sysCalendar")
public class SysCalendarController {

    private final SysCalendarService sysCalendarService;

    private final SysSchedulePermissionsService sysSchedulePermissionsService;

//    private final RabbitTemplate rabbitTemplate;

    private final SysCalendarFeedBackService sysCalendarFeedBackService;

//    private final SysCalendarPersonnelService sysCalendarPersonnelService;
    @DubboReference
    private final RemoteUserService remoteUserService;
    @DubboReference
    private final RemoteDeptService remoteDeptService;

    private final SysCalendarSharingService sysCalendarSharingService;

    private final SysResourceService sysResourceService;


    private final SysScheduleService sysScheduleService;

    private final SysCalendarTypeService sysCalendarTypeService;

    private final SysCalendarWorkService sysCalendarWorkService;


//    @GetMapping("/query")
////    @Log("查询用户日历信息")
////    @ApiOperation("查询用户日历信息")
//    public R<SysCalendarDto> query(SysCalendarQueryParam query, Pageable pageable){
//        PageInfo<SysCalendarDto> info = sysCalendarService.queryAll(query,pageable);
//        return R.okPage(info.getContent(), info.getTotalElements(), info.getSize());
//    }

    @GetMapping("/queryInterval")
//    @Log("查询用户日历信息")
//    @ApiOperation("查询用户日历信息")
    public R<List<SysCalendarDto>> queryInterval(@Valid @ModelAttribute SysCalendarQueryParam query){
        List<SysCalendarDto> sysCalendarDtos = sysCalendarService.queryAll(query);
        return R.ok(sysCalendarDtos);
    }

    @GetMapping("/page/queryInterval")
//    @Log("分页显示用户日历信息")
//    @ApiOperation("分页显示用户日历信息")
    public R<TableDataInfo<SysCalendarDto>> queryPageInterval(@Valid @ModelAttribute SysCalendarQueryParam query, Pageable pageable){
        TableDataInfo<SysCalendarDto> sysCalendarDtoTableDataInfo = sysCalendarService.queryPageAll(query, pageable);

        return R.ok(sysCalendarDtoTableDataInfo);
    }


    @PutMapping("/state")
//    @Log("修改日历状态")
//    @ApiOperation("修改日历状态")
//    @PreAuthorize("@el.check('sysCalendar:edit')")
    public R update(@RequestBody SysCalendar sysCalendar){
        return R.ok(sysCalendarService.updateById(sysCalendar));
    }

    @GetMapping("/get-permissions-schedule")
//    @ApiOperation("查询出有创建日程权限的日历")
    public R<List<SysSchedule>> getPermissionsSchedule() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        return R.ok(sysSchedulePermissionsService.checkPermissions(loginUser.getUserId()));
    }

    @PostMapping("/create")
//    @Log("新增用户日历信息")
//    @ApiOperation("新增用户日历信息")
//    @PreAuthorize("@el.check('sysCalendar:add')")
    public R create(@Valid @RequestBody SysCalendarInsertDto resources){

        if(ObjectUtils.isEmpty(resources.getStartDate())){
            throw new RuntimeException("开始时间,不得为空");
        }
        if(ObjectUtils.isNotEmpty(resources.getEndDate())){
            if (DateUtil.judgeDifference(resources.getStartDate(),resources.getEndDate())){
                throw new RuntimeException("开始时间,不得大于结束时间");
            }
        }
        SysCalendarDto convert = MapstructUtils.convert(resources, SysCalendarDto.class);
        boolean insert = sysCalendarService.insert(convert);
        if (insert == false) {
            return R.fail("406", "选择资源中在选择的日程期间内正在被使用！");
        }
        return R.ok(insert);
    }

    @PostMapping("/update")
//    @Log("修改用户日历信息")
//    @ApiOperation("修改用户日历信息")
//    @PreAuthorize("@el.check('sysCalendar:edit')")
    public R update(@Validated @RequestBody SysCalendarUpdateDto resources){
//        Date startDate = resources.getStartDate();
//        Date endDate = resources.getEndDate();
//        LocalDateTime localDateTime = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
//        LocalDateTime localDateTime1 = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//        String startTime = localDateTime.format(dateTimeFormatter);
//        String endTime = localDateTime1.format(dateTimeFormatter);
        if(ObjectUtils.isEmpty(resources.getStartDate())){
            throw new RuntimeException("开始时间,不得为空");
        }

        if(ObjectUtils.isNotEmpty(resources.getEndDate())){
            if (DateUtil.judgeDifference(resources.getStartDate(),resources.getEndDate())){
                throw new RuntimeException("开始时间,不得大于结束时间");
            }
        }
        SysCalendarDto convert = MapstructUtils.convert(resources, SysCalendarDto.class);
        LoginUser user = LoginHelper.getLoginUser();
        SysCalendarSharing sysCalendarSharing = sysCalendarSharingService.getOne(new QueryWrapper<SysCalendarSharing>().eq("calendar_id", convert.getId()));
        List<Long> userIdList = JSONUtil.toList(sysCalendarSharing.getCalendarSharingId(), Long.class);
        SysCalendar sysCalendar = sysCalendarService.getOne(new QueryWrapper<SysCalendar>().eq("id", convert.getId()));
        if (!userIdList.contains(user.getUserId()) && !user.getUserId().equals(Long.parseLong(sysCalendar.getCreateId()))) {
            return R.fail("406" ,"你不是参与人员不能编辑权限");
        }
        Boolean state = sysSchedulePermissionsService.checkPermissionsById(convert.getScheduleId(), user.getUserId(), "编辑日程");
        if (state.equals(false) && !user.getUserId().equals(Long.parseLong(sysCalendar.getCreateId()))) {
            return R.fail("406" ,"你没有权限编辑日程信息!");
        }
        //先删除这个日历对应的资源的时间表中的数据
//        List<SysCalendar> sysCalendarList = sysCalendarService.list(new QueryWrapper<SysCalendar>().in("id", resources.getId()));
//        QueryWrapper<SysResourcePlan> deleteWrapper  = new QueryWrapper<>();
        // 添加多个or条件
//        sysCalendarList.forEach(sysCalendar1 -> {
//            List<Long> resourceIds = JSONUtil.toList(sysCalendar1.getResourceId(), Long.class);
//            resourceIds.forEach(resourceId -> {
//                deleteWrapper.or(w -> w.eq("resource_id", resourceId)
//                        .eq("resource_start_time", sysCalendar1.getStartDate())
//                        .eq("resource_end_time", sysCalendar1.getEndDate()));
//            });
//        });
//        sysResourcePlanService.remove(deleteWrapper);
//        //删除后再判断资源时间段是否有占用的情况
//        if (resources.getResourceIds() != null && !resources.getResourceIds().isEmpty() ) {
//            List<SysResourcePlan> sysResourcePlans = sysResourcePlanService.list(
//                    new QueryWrapper<SysResourcePlan>()
//                            .in("resource_id", resources.getResourceIds())
//                            .and(wrapper -> wrapper
//                                    .or(w -> w.between("resource_start_time", startTime, endTime))
//                                    .or(w -> w.between("resource_end_time", startTime, endTime))
//                                    .or(w -> w.le("resource_start_time", startTime).ge("resource_end_time", startTime))
//                                    .or(w -> w.le("resource_start_time", endTime).ge("resource_end_time", endTime))
//                            )
//            );
//            if (!sysResourcePlans.isEmpty()) {
//                return R.fail("406" ,"选择资源中在选择的日程期间内正在被使用！");
//            }
//        }
//        //判断通过重新插入新的时间数据
//        List<SysResourcePlan> sysResourcePlanList = new ArrayList<>();
//        if (resources.getResourceIds() != null) {
//            resources.getResourceIds().forEach(v -> {
//                SysResourcePlan sysResourcePlan = new SysResourcePlan();
//                sysResourcePlan.setResourceId(v);
//                sysResourcePlan.setResourceEndTime(resources.getEndDate());
//                sysResourcePlan.setResourceStartTime(resources.getStartDate());
//                sysResourcePlanList.add(sysResourcePlan);
//            });
//            sysResourcePlanService.saveBatch(sysResourcePlanList);
//        }
        return R.ok(sysCalendarService.updateById(convert));
    }

    @PostMapping("/delete")
//    @Log("删除用户日历信息")
//    @ApiOperation("删除用户日历信息")
//    @PreAuthorize("@el.check('sysCalendar:del')")
    public R delete(@RequestBody Set<Long> ids) {
        AtomicReference<Boolean> state = new AtomicReference<>(true);
        LoginUser loginUser = LoginHelper.getLoginUser();
        AtomicReference<SysCalendar> sysCalendar2 = new AtomicReference<>(new SysCalendar());
        ids.forEach(id -> {
            SysCalendarSharing sysCalendarSharing = sysCalendarSharingService.getOne(new QueryWrapper<SysCalendarSharing>().eq("calendar_id", id));
            List<Long> userIdList = JSONUtil.toList(sysCalendarSharing.getCalendarSharingId(), Long.class);
            if (!userIdList.contains(loginUser.getUserId())) {
                state.set(false);
            }
            sysCalendar2.set(sysCalendarService.getOne(new QueryWrapper<SysCalendar>().eq("id", id)));
        });
        if (!state.get().booleanValue()  && !loginUser.getUserId().equals(Long.parseLong(sysCalendar2.get().getCreateId()))) {
            return R.fail("406", "你不是参与人员不能删除日程");
        }
        if (!ids.isEmpty()) {
            AtomicReference<Boolean> status = new AtomicReference<>(true);
            LoginHelper.getLoginUser();
            ids.forEach(v -> {
                SysCalendar sysCalendar = sysCalendarService.getOne(new QueryWrapper<SysCalendar>().eq("id", v));
                if (sysSchedulePermissionsService.checkPermissionsById(sysCalendar.getScheduleId(), loginUser.getUserId(), "编辑日程").equals(false)) {
                    status.set(false);
                }

            });
            if (!status.get().booleanValue() && !loginUser.getUserId().equals(Long.parseLong(sysCalendar2.get().getCreateId()))) {
                return R.fail("406", "你没有权限删除日程");
            }
//            List<SysCalendar> sysCalendarList = sysCalendarService.list(new QueryWrapper<SysCalendar>().in("id", ids));
//            QueryWrapper<SysResourcePlan> deleteWrapper  = new QueryWrapper<>();
            // 添加多个or条件
//            sysCalendarList.forEach(sysCalendar -> {
//                List<Long> resourceIds = JSONUtil.toList(sysCalendar.getResourceId(), Long.class);
//                resourceIds.forEach(resourceId -> {
//                    deleteWrapper.or(w -> w.eq("resource_id", resourceId)
//                            .eq("resource_start_time", sysCalendar.getStartDate())
//                            .eq("resource_end_time", sysCalendar.getEndDate()));
//                });
//            });

//            sysResourcePlanQueryWrapper.in("resource_id", resourceIds);
//            sysCalendarList.forEach(sysCalendar -> {
//                sysResourcePlanQueryWrapper.and(w -> w.eq("resource_start_time", sysCalendar.getStartDate())
//                        .eq("resource_end_time", sysCalendar.getEndDate()));
//            });
//            sysResourcePlanService.remove(deleteWrapper);
            return R.ok(sysCalendarService.deleteByIds(ids));
        }
        return R.ok("删除成功");
    }

    @PostMapping("/update-feed-back")
//    @Log("修改日程的个人状态")
//    @ApiOperation("修改日程的个人状态")
    public R updateFeedBack(@RequestBody FeedBackDTO feedBackDTO) {
        LoginUser user = LoginHelper.getLoginUser();
        SysCalendar sysCalendar = sysCalendarService.getOne(new QueryWrapper<SysCalendar>().eq("id", feedBackDTO.getId()));
        //判断参与人
        SysCalendarSharing sysCalendarSharing = sysCalendarSharingService.getOne(new QueryWrapper<SysCalendarSharing>().eq("calendar_id", feedBackDTO.getId()));
        List<Long> userIdList = JSONUtil.toList(sysCalendarSharing.getCalendarSharingId(), Long.class);
        if (userIdList.contains(user.getUserId()) && !user.getUserId().equals(Long.parseLong(sysCalendar.getCreateId()))) {
            return R.fail("406" ,"你不是参与人员不能修改状态");
        }
        //判断权限
        Boolean state = sysSchedulePermissionsService.checkPermissionsById(feedBackDTO.getId(), user.getUserId(), "编辑日程");
        if (state.equals(false) && !user.getUserId().equals(Long.parseLong(sysCalendar.getCreateId()))) {
            return R.fail("406" ,"你没有权限修改状态");
        }
        sysCalendarFeedBackService.remove(new QueryWrapper<SysCalendarFeedBack>().eq("calendar_id", feedBackDTO.getId()).eq("user_id", user.getUserId()));
        SysCalendarFeedBack sysCalendarFeedBack = new SysCalendarFeedBack();
        sysCalendarFeedBack.setFeedBack(feedBackDTO.getFeedBack());
        sysCalendarFeedBack.setUserId(user.getUserId());
        sysCalendarFeedBack.setCalendarId(feedBackDTO.getId());
        sysCalendarFeedBackService.save(sysCalendarFeedBack);
        return R.ok("修改成功");
    }

    /*
//    @Log("导出用户日历信息")
//    @ApiOperation("导出用户日历信息")
    @GetMapping(value = "/download")
    @PreAuthorize("@el.check('sysCalendar:list')")
    public void download(HttpServletResponse response, SysCalendarQueryParam query) throws IOException {
        sysCalendarService.download(sysCalendarService.queryAll(query), response);
    }*/

//    @GetMapping("/test-send-message")
////    @Log("测试延时消息")
////    @ApiOperation("测试延时消息")
//    public R testSendMessage() {
//        // 示例：创建并发送一个 10 秒的延时消息
//        rabbitTemplate.convertAndSend(RabbitmqConfig.ECM_CALENDAR_EXCHANGE, RabbitmqConfig.ECM_CALENDAR_DELAY_ROUTING, "test-delay-message", m -> {
//            m.getMessageProperties().setExpiration(String.valueOf(10000)); // 10 秒
//            m.getMessageProperties().setDeliveryMode(MessageProperties.DEFAULT_DELIVERY_MODE.PERSISTENT);
//            return m;
//        });
//        System.out.println("延时消息已创建并发送"+ new Date().toString());
//        return R.ok("延时消息已创建并发送");
//    }


    @GetMapping("/get-detail-show/{id}")
//    @Log("获取日程详情显示")
//    @ApiOperation("获取日程详情显示")
    public R<Map<String, Object>> getDetailShow(@PathVariable("id") Long calendarId) {
        Map<String, Object> data = new HashMap<>(16);
        //日历信息
        SysCalendar sysCalendar = sysCalendarService.getOne(new QueryWrapper<SysCalendar>().eq("id", calendarId));
        CalendarVO calendarVO = new CalendarVO();
        RemoteUserVo loginUser = remoteUserService.selectUserByUserId(Long.valueOf(sysCalendar.getCreateId()));

        BeanCopyUtil.copyProperties(sysCalendar, calendarVO);
        calendarVO.setCreateName(loginUser.getNickName());
        if (calendarVO.getType() != null) {
            SysCalendarType sysCalendarType = sysCalendarTypeService.getOne(new QueryWrapper<SysCalendarType>().eq("value", calendarVO.getType()));
            if(sysCalendarType != null && sysCalendarType.getName() != null) {
                calendarVO.setTypeName(sysCalendarType.getName());
            }
        }
        SysCalendarWork sysCalendarWork = sysCalendarWorkService.getOne(new QueryWrapper<SysCalendarWork>()
                .eq("calendar_id", calendarId)
                .eq("user_id", loginUser.getUserId()));
        if (sysCalendarWork != null && sysCalendarWork.getWorkHours() != null) {
            calendarVO.setWorkHours(sysCalendarWork.getWorkHours());
        }
        data.put("calendar", calendarVO);
        //参与人员的信息
        SysCalendarSharing sysCalendarSharing = sysCalendarSharingService.getOne(new QueryWrapper<SysCalendarSharing>().eq("calendar_id", calendarId));
        List<Long> userIds = JSONUtil.toList(sysCalendarSharing.getCalendarSharingId(), Long.class);
//        String calendarSharingId = sysCalendarSharing.getCalendarSharingId();
//        String[] parts = calendarSharingId.replaceAll("\\[|\\]|\\s", "").split(",");
//        List<Long> userIds = Arrays.stream(parts)
//                .filter(StringUtils::isNotBlank) // 使用 StringUtils.isNotBlack 过滤空字符串
//                .map(Long::valueOf)
//                .collect(Collectors.toList());
        //参与人员
        List<RemoteUserVo> userList = new ArrayList<>();
        if (!userIds.isEmpty()) {
            userList = remoteUserService.selectListByIds(userIds);
        }
        data.put("userList", userList);
        //参与人员的状态
        List<SysCalendarFeedBack> sysCalendarFeedBackList = new ArrayList<>();
        if (!userIds.isEmpty()) {
            sysCalendarFeedBackList = sysCalendarFeedBackService.list(new QueryWrapper<SysCalendarFeedBack>().eq("calendar_id", calendarId).in("user_id", userIds));
        }
        Map<Long, SysCalendarFeedBack> sysCalendarFeedBackMap = sysCalendarFeedBackList.stream().collect(Collectors.toMap(SysCalendarFeedBack::getUserId, feedback -> feedback));
//        Map<Long, Dept> deptMap = sysDeptService.list().stream().collect(Collectors.toMap(Dept::getId, dept -> dept));

        List<UserVO> userVOList = new ArrayList<>();
        userList.forEach(v -> {
            UserVO userVO = new UserVO();
            if (sysCalendarFeedBackMap.containsKey(v.getUserId())) {
                userVO.setUserId(v.getUserId());
                userVO.setUserName(v.getNickName());
                userVO.setFeedBack(sysCalendarFeedBackMap.get(v.getUserId()).getFeedBack());
                userVO.setDeptName(remoteDeptService.getById(v.getDeptId()).getDeptName());
                userVOList.add(userVO);
            }else {
                userVO.setUserId(v.getUserId());
                userVO.setUserName(v.getNickName());
                userVO.setFeedBack("tentative");
                userVO.setDeptName(remoteDeptService.getById(v.getDeptId()).getDeptName());
                userVOList.add(userVO);
            }
        });
        data.put("userFeedBack", userVOList);
        //资源信息
        String resourceId = calendarVO.getResourceId();
        List<SysResource> sysResourceList = new ArrayList<>();
        if (resourceId != null) {
            String[] resourceIds = resourceId.replaceAll("\\[|\\]|\\s", "").split(",");
            List<Long> resourceIdList = Arrays.stream(resourceIds)
                    .filter(StringUtils::isNotBlank)
                    .map(Long::valueOf)
                    .collect(Collectors.toList());
            if (!resourceIdList.isEmpty()) {
                sysResourceList = sysResourceService.list(new QueryWrapper<SysResource>().in("resource_id", resourceIdList));
            }
            data.put("resource", sysResourceList);
        }
        data.put("resource", sysResourceList);
        //当前人员的状态
        LoginUser user = LoginHelper.getLoginUser();
        SysCalendarFeedBack sysCalendarFeedBack = sysCalendarFeedBackService.getOne(new QueryWrapper<SysCalendarFeedBack>().eq("calendar_id", calendarId).eq("user_id", user.getUserId()));
        if (sysCalendarFeedBack == null) {
            data.put("userBack", "tentative");
        } else {
            data.put("userBack", sysCalendarFeedBack.getFeedBack());
        }
        //返回日历的信息
        SysSchedule sysSchedule = new SysSchedule();
        if (sysCalendar.getScheduleId() != null) {
            sysSchedule = sysScheduleService.getOne(new QueryWrapper<SysSchedule>().eq("id", sysCalendar.getScheduleId()));
            data.put("schedule", sysSchedule);
        }else {
            data.put("schedule", sysSchedule);
        }
        return R.ok(data);
    }

    @GetMapping("/get-weekly")
//    @Log("根据当前日期获取周报内容")
//    @ApiOperation("根据当前日期获取周报内容")
    public R getWeekly(@RequestParam Map<String, Object> params) throws ParseException {
        String username = MapUtils.getString(params, "username");
        String startTime = MapUtils.getString(params, "startTime");
        if ( startTime != null ) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date parse = format.parse(startTime);
            Calendar instance = Calendar.getInstance();
            instance.setTime(parse);
            int i = instance.get(Calendar.DAY_OF_WEEK);
            if ( i != Calendar.MONDAY) {
                return R.fail("406", "起始时间不是周一！！");
            }

        }
        return R.ok(sysCalendarService.getWeekly(startTime, username));
    }


    @PostMapping("/mission-to-calendar")
//    @Log("测试我的任务加入我的日程中")
//    @ApiModelProperty("测试我的任务加入我的日程中")
    public R missionToCalendar(@RequestBody MissionToCalendarDTO missionToCalendarDTO) {
        sysCalendarService.fromMissionToCalenadr(missionToCalendarDTO);
        return R.ok("添加成功");
    }

    @PostMapping("/mission-upate-calendar")
//    @Log("测试修改我的任务")
//    @ApiOperation("测试修改我的任务")
    public R missionUpdateCalendar(@RequestBody MissionToCalendarDTO missionToCalendarDTO) {
        return R.ok(sysCalendarService.updateMissionCalendar(missionToCalendarDTO));
    }

//    @DeleteMapping("/mission-delete-calendar")
////    @ApiOperation("测试删除我的任务")
//    public

}
